package com.cl.blog.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cl.blog.common.Const;
import com.cl.blog.document.MailDto;
import com.cl.blog.entity.*;
import com.cl.blog.exception.WebException;
import com.cl.blog.mapper.*;
import com.cl.blog.po.InterestPo;
import com.cl.blog.service.*;
import com.cl.blog.util.IpUtil;
import com.cl.blog.util.JwtUtil;
import com.cl.blog.util.RedisUtil;
import com.cl.blog.vo.LoginVo;
import com.cl.blog.vo.RegisterUserVo;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author object
 * @description 针对表【b_user】的数据库操作Service实现
 * @createDate 2024-03-15 14:39:07
 */
@Service
public class BUserServiceImpl extends ServiceImpl<BUserMapper, BUser>
		implements BUserService {
	@Resource
	JwtUtil jwtUtil;
	@Resource
	MailService mailService;
	@Autowired
	BUserLikeMapper bUserLikeMapper;
	@Autowired
	RedisUtil redisUtil;

	@Autowired
	BContentMapper bContentMapper;
	@Autowired
	BNoticeService bNoticeService;

	// 收藏表
	@Autowired
	BCollectService bCollectService;

	// 文章评论
	@Autowired
	BContentReviewMapper bContentReviewMapper;
	@Autowired
	BTypeMapper bTypeMapper;
	// 历史观看
	@Autowired
	BHistoryLookService bHistoryLookService;
	//用户关注
	@Autowired
	BUserFollowService bUserFollowService;
	@Autowired
	BUserLikeService bUserLikeService;
	@Autowired
	RedisTemplate redisTemplate;
	@Autowired
	RankingSerivce rankingSerivce;

	@Override
	public BUser login(LoginVo loginVo) {
		if (!loginVo.getCode().equals(redisUtil.get(loginVo.getUuid()))) {
			throw new WebException("抱歉，验证码错误");
		}
		//验证账号密码是否正确
		BUser bUser = this.getOne(new QueryWrapper<BUser>().eq("username", loginVo.getUsername()));
		Assert.notNull(bUser, "抱歉，用户名或密码错误");
		System.out.println(loginVo.getPassword() + "---" + SecureUtil.md5(loginVo.getPassword()) + "---" + bUser.getPassword());
		System.out.println(bUser.getPassword().equals(SecureUtil.md5(loginVo.getPassword())));
		Assert.isTrue(bUser.getPassword().equals(SecureUtil.md5(loginVo.getPassword())), "账号或密码错误");
		Assert.isTrue(bUser.getIsDelete() == 0, "抱歉，当前账号已封禁");

		bUser.setIsLogin(1);
		bUser.setLoginTime(LocalDateTime.now());

		this.updateById(bUser);


		return bUser;
	}

	@Override
	public void logout(String userId) {
		BUser bUser = this.getById(userId);
		bUser.setIsLogin(0);

		this.updateById(bUser);

	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean banByUserId(Integer id, HttpServletRequest request) {
		boolean update = this.update(new UpdateWrapper<BUser>().eq("id", id)
				.set("is_delete", 1)
		);
		return update;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean deleteById(Integer id, HttpServletRequest request) throws Exception {
		BUser bUser = this.getById(id);
		Assert.notNull(bUser, "抱歉，当前用户已删除");

		boolean b = this.removeById(id);

		List<String> list = new ArrayList<>();
		list.add(bUser.getEmil());
		if (b) {
			MailDto mailDto = new MailDto();
			mailDto.setSubject("通知");
			mailDto.setContent("你的账户已被管理员删除");
			mailDto.setTos(list);
			mailService.ostSeander(mailDto);
			return true;
		}

		return false;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public BUser insertUser(RegisterUserVo registerUser) {
		BUser username = this.getOne(new QueryWrapper<BUser>().eq("username", registerUser.getUsername()));
		System.out.println(username);
		Assert.isNull(username, "抱歉，当前用户已存在");


		BUser bUser = new BUser();
		bUser.setNickname(registerUser.getNickname().isEmpty() ? registerUser.getUsername() : registerUser.getNickname());
		bUser.setUsername(registerUser.getUsername());
		bUser.setPassword(SecureUtil.md5(registerUser.getPassword()));
		bUser.setIsDelete(0);
		bUser.setCreateTime(LocalDateTime.now());
		bUser.setEmil(registerUser.getEmail().isEmpty() ? null : registerUser.getEmail());
		bUser.setAvatar(registerUser.getAvatar());
		bUser.setIsLogin(0);

		boolean save = this.save(bUser);
		if (!save) {
			throw new WebException("新增失败");
		}

		return bUser;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public BUser register(LoginVo loginVo) {

		BUser bUser = this.getOne(new QueryWrapper<BUser>().eq("username", loginVo.getUsername()));
		Assert.isNull(bUser, "抱歉，当前用户已存在");

		BUser bUser1 = new BUser();
		bUser1.setUsername(loginVo.getUsername());
		if (!loginVo.getEmail().isEmpty()) {
			bUser1.setEmil(loginVo.getEmail());
		}
		bUser1.setPassword(loginVo.getPassword());
		bUser1.setCreateTime(LocalDateTime.now());
		bUser1.setIsLogin(0);
		bUser1.setIsDelete(0);
		bUser1.setNickname(loginVo.getUsername());


		boolean b = this.save(bUser1);
		if (!b) {
			throw new WebException("注册失败");
		}


		return bUser1;
	}

	@Override
	public BUser getCurrentId(String token) {
		if (token.isEmpty()) {
			return null;
		}
		Claims claim = jwtUtil.getClaimByToken(token, Const.GRADE_USER);
		String userId = claim.getSubject();

		BUser bUser = this.getOne(new QueryWrapper<BUser>().eq("id", Integer.valueOf(userId)));


		return bUser;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Map<Object, Object> getUserInfo(Integer contentId, Integer id, String token) {

		BUser bUser = this.getById(id);
		BUser currentUser = getCurrentId(token);
		// 获取用户发布文章列表
		List<BContent> list = bContentMapper.selectList(new QueryWrapper<BContent>().eq("user_id", id)
				.eq("status", 2)
				.eq("is_delete", 0)
		);

		List<Integer> contentIds = list.stream().map(BContent::getId).collect(Collectors.toList());
		List<Long> collects = list.stream().map(BContent::getCollect).collect(Collectors.toList());
		List<Long> history = list.stream().map(BContent::getHistoryPeopleCount).collect(Collectors.toList());

		// 获取用户粉丝数量
		long followCount = bUserFollowService.count(new QueryWrapper<BUserFollow>()
				.eq("follow_user_id", id)
		);
		// 获取用户获赞数量
		long likeCount = bContentMapper.selectLikeCount(id);
		// 获取用户被评论数量
		long reviewCount = 0;
		// 历史访问总量
		long historyCount = 0;
		// 获取用户收藏数量
		long collectCount = 0;
		for (Integer Id : contentIds) {
			reviewCount += bContentReviewMapper.selectCount(new QueryWrapper<BContentReview>().eq("content_id", Id));
		}
		for (int i = 0; i < collects.size(); i++) {
			collectCount += collects.get(i);
			historyCount += history.get(i);
		}

		// 当前登录用户是否收藏当前文章
		boolean isCollect = false;
		// 当前登录用户是否关注该文章用户
		boolean isFollow = false;
		// 当前登录用户是否点赞该文章
		boolean isLike = false;

		// 将访问量存储到redis
		// 存储key：用户id+文章id+-属性名称
		String key = id + "-" + contentId + "-history";

		redisUtil.incre(key);

		if (bUser.getId().equals(currentUser.getId())) {
			// 当前登录用户是否收藏了当前文章
			long number = bCollectService.count(new QueryWrapper<BCollect>().eq("user_id", currentUser.getId())
					.eq("content_id", contentId)
			);
			if (number >= 1) {
				isCollect = true;
			}
			long count1 = bUserFollowService.count(new QueryWrapper<BUserFollow>()
					.eq("user_id", currentUser.getId())
					.eq("follow_user_id", bUser.getId())
			);

			System.out.println("是否关注" + count1);
			if (count1 >= 1) {
				isFollow = true;
			}
			long count2 = bUserLikeService.count(new QueryWrapper<BUserLike>()
					.eq("user_id", currentUser.getId())
					.eq("content_id", contentId));
			if (count2 >= 1) {
				isLike = true;
			}
		}

		long count = bHistoryLookService.count(new QueryWrapper<BHistoryLook>()
				.eq("user_id", currentUser.getId())
				.eq("content_id", contentId)
		);
		if (count <= 0) {
			BHistoryLook bHistoryLook = new BHistoryLook();
			bHistoryLook.setContentId(contentId);
			bHistoryLook.setUserId(currentUser.getId());
			bHistoryLook.setCreateTime(LocalDateTime.now());

			bHistoryLookService.save(bHistoryLook);
		} else {
			bHistoryLookService.update(new UpdateWrapper<BHistoryLook>()
					.eq("user_id", currentUser.getId())
					.eq("content_id", contentId)
					.set("create_time", LocalDateTime.now()));
		}

		return MapUtil.builder()
				.put("userInfo", bUser)
				.put("followCount", followCount)
				.put("likeCount", likeCount)
				.put("reviewCount", reviewCount)
				.put("collectCount", collectCount)
				.put("isCollect", isCollect)
				.put("isFollow", isFollow)
				.put("isLike", isLike)
				.put("contentCount", list.size())
				.put("historyCount", historyCount)
				.build();
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int like(Integer contentId, String token) {
		int i = 0;
		BUser currentUser = this.getCurrentId(token);
		long count = bUserLikeService.count(new QueryWrapper<BUserLike>().eq("user_id", currentUser.getId()).eq("content_id", contentId));
		if (count <= 0) {
			BUserLike bUserLike = new BUserLike();
			bUserLike.setUserId(currentUser.getId());
			bUserLike.setContentId(contentId);
			bUserLike.setCreateTime(LocalDateTime.now());

			bUserLikeService.save(bUserLike);
			bContentMapper.addLike(contentId);
			i = 1;
		} else {
			boolean userId = bUserLikeService.remove(new QueryWrapper<BUserLike>().eq("user_id", currentUser.getId()).eq("content_id", contentId));
			bContentMapper.subtractLike(contentId);

		}

		return i;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int collect(Integer contentId, String token) {
		int i = 0;
		BUser currentUser = this.getCurrentId(token);
		long count = bCollectService.count(new QueryWrapper<BCollect>().eq("user_id", currentUser.getId()).eq("content_id", contentId));
		// 用户没有收藏文章
		if (count <= 0) {
			BCollect bCollect = new BCollect();
			bCollect.setUserId(currentUser.getId());
			bCollect.setContentId(contentId);
			bCollect.setCreateTime(LocalDateTime.now());

			bCollectService.save(bCollect);
			bContentMapper.addCollect(contentId);
			i = 1;
		} else {
			boolean userId = bCollectService.remove(new QueryWrapper<BCollect>().eq("user_id", currentUser.getId()).eq("content_id", contentId));
			bContentMapper.subtractCollect(contentId);
		}

		return i;
	}


	@Override
	public Object getUser(Integer userId, HttpServletRequest request) {

		IpUtil ipUtil = new IpUtil();
		String ipAddr = ipUtil.getIpAddr(request);
		boolean b = IpUtil.checkIp(ipAddr);
		String ipRegion = null;
		if (b) {
			ipRegion = IpUtil.getIpRegion(ipAddr);
		}


		// 获取用户信息
		BUser bUser = this.getById(userId);
		// 获取用户排名
		Object userRanking = rankingSerivce.getUserRanking(userId);
		// 获取用户的文章列表，已发布、审核中、延时发布、草稿箱等
		List<BContent> bContentList = bContentMapper.selectList(new QueryWrapper<BContent>()
				.eq("user_id", userId)
				.eq("is_delete", 0)
				.orderByDesc("create_time")
		);

		List<Integer> contentIds = bContentList.stream().map(BContent::getId).collect(Collectors.toList());
		// 用户的粉丝数量
		List<BUserFollow> followList = bUserFollowService.list(new QueryWrapper<BUserFollow>()
				.eq("follow_user_id", userId)
		);
		// 获取总点赞量
		Long likeCount = bContentMapper.getLikeCount(userId);
		// 获取总访问量
		Long history = bContentMapper.getHistory(userId);
		// 获取总收藏量
		Long collectCount = bContentMapper.getCollectCount(userId);
		// 文章总评论量

		long reviewCount = 0L;

		if (contentIds.size() > 0) {
			reviewCount = bContentReviewMapper.getReviewCount(contentIds);
		}
		System.out.println("评论数量->" + reviewCount);
		// 获取每一年的文章数量 year-dataCount
		List<Object> yearCount = bContentMapper.getYearCount(userId);
		// 获取用户的兴趣领域，获取文章不同分类的所有数量
		List<Object> interestCount = bContentMapper.getTypeCount(userId);
		for (Object interestPo : interestCount) {
			System.out.println("---->" + interestPo);
			InterestPo po = (InterestPo) interestPo;

			String[] split = po.getTagsName().split(",");

			// 使用LinkedHashSet来保持插入顺序并自动去除重复项
			Set<String> uniqueTags = new LinkedHashSet<>();
			for (String tag : split) {
				// 去除可能的空白字符，并添加到Set中
				uniqueTags.add(tag.trim());
			}

			// 将Set转换回数组（如果需要）
			String[] uniqueTagsArray = uniqueTags.toArray(new String[0]);

			// 将Set转换回字符串，使用逗号作为分隔符
			po.setTagsName(String.join(",", uniqueTags));
		}
		// 获取公告,只截取前三的
		List<BNotice> noticeList = bNoticeService.list(new QueryWrapper<BNotice>()
				.eq("title", "公告")
				.isNull("userId")
				.eq("status", 0)
				.orderByDesc("create_time")
				.last("limit 3")
		);

		return MapUtil.builder()
				.put("user", bUser)
				.put("rank", userRanking)
				.put("contents", bContentList)
				.put("follows", followList)
				.put("like", likeCount)
				.put("history", history)
				.put("collect", collectCount)
				.put("review", reviewCount)
				.put("year", yearCount)
				.put("interest", interestCount)
				.put("notice", noticeList)
				.put("ipRegion", ipRegion)
				.build();
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean deleteByIdAndStatus(Integer id, Integer status, HttpServletRequest request) {
		// 获取当前登录用户信息
		String token = request.getHeader("token");
		Claims claim = jwtUtil.getClaimByToken(token, Const.GRADE_USER);
		// 判断
		if (status == 1) {
			// 删除文章
			int delete = bContentMapper.delete(new QueryWrapper<BContent>()
					.eq("user_id", Integer.valueOf(claim.getSubject()))
					.eq("id", id)
			);
			if (delete > 0) {
				return true;
			}
		} else if (status == 2) {
			// 取消收藏
			boolean b = bCollectService.remove(new QueryWrapper<BCollect>()
					.eq("user_id", Integer.valueOf(claim.getSubject()))
					.eq("content_id", id)
			);
			bContentMapper.cancelCollect(id);
			return b;
		} else if (status == 3) {
			// 取消点赞
			boolean remove = bUserLikeService.remove(new QueryWrapper<BUserLike>()
					.eq("user_id", Integer.valueOf(claim.getSubject()))
					.eq("content_id", id)
			);
			bContentMapper.cancelLike(id);
			return remove;
		}

		return false;
	}
}




